package com.neutech.maplestory.entity;

import com.neutech.maplestory.client.MapleStoryClient;
import com.neutech.maplestory.constant.Constant;
import com.neutech.maplestory.util.ImageUtil;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;

public class Hero extends AbstractMapleStoryObject{
    public static Image[] imgs = new Image[100];
    static {
        for (int i = 0; i < 4; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_stand" + i);
        }
        for (int i = 4; i < 8; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_stand" + (i - 4));
        }
        for (int i = 8; i < 13; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_walk" + (i - 8));
        }
        for (int i = 13; i < 18; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_walk" + (i - 13));
        }
        imgs[18] = ImageUtil.getImage("hero_right_prone");

        imgs[19] = ImageUtil.getImage("hero_left_prone");

        imgs[20] = ImageUtil.getImage("hero_right_jump");

        imgs[21] = ImageUtil.getImage("hero_left_jump");
        for (int i = 22; i < 26; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_shoot" + (i - 22));
        }
        for (int i = 26; i < 30; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_shoot" + (i - 26));
        }
    }

    public MapleStoryClient msc;

    public Hero(){}

    /**
     * 人物血量上限
     */
    public int MAX_HP = 1000;
    public int HP;
    /**
     * 人物魔法值上限
     */
    public int MAX_MP = 1000;
    public int MP;
    /**
     *人物等级
     */
    public int LEVEL = 1;
    /**
     * 基础攻击力
     */
    public int ATT;
    /**
     * 伤害值
     */
    public int hitValue;

    public Random r = new Random();

    public Hero(MapleStoryClient msc,int x,int y){
        this.msc = msc;
        this.x = x;
        this.y = y;
        this.HP = MAX_HP;
        this.MP = MAX_MP;
        this.ATT = 1000;
        this.speed = Constant.HERO_SPEED;
        this.width = imgs[0].getWidth(null);
        this.height = imgs[0].getHeight(null);
        this.dir = Direction.RIGHT;
        this.action = Action.STAND;
    }

    /**
     * 一直加的计数器
     */
    public int count = 0;
    /**
     * 计算当前画第几张图
     */
    private int step = 0;
    /**
     * 左右的开关
     */
    public boolean left,right,down,jump,jump_again,shoot,pickup;

    @Override
    public void draw(Graphics g) {
        Font f = g.getFont();
        g.setFont(new Font("微软雅黑",Font.BOLD,24));
        g.drawString("LV" + this.LEVEL,this.x + 10,this.y - 20);
        g.setFont(f);
        switch (dir){
            case RIGHT:
                switch (action){
                    case STAND:
                        // right stand
                        if (count++ % 3 == 0){
                            g.drawImage(imgs[step++ % 4],x,y,null);
                        }else {
                            g.drawImage(imgs[step % 4],x,y,null);
                        }
                        break;
                    case WALK:
                        // right walk
                        if (count++ % 3 == 0){
                            g.drawImage(imgs[step++ % 5 + 8],x,y,null);
                        }else {
                            g.drawImage(imgs[step % 5 + 8],x,y,null);
                        }
                        break;
                    case PRONE:
                        // right prone
                        g.drawImage(imgs[18],x + 5,y + 35,null);
                        break;
                    case JUMP:
                        // right jump
                        g.drawImage(imgs[20],x,y,null);
                        break;
                    case SHOOT:
                        // right shoot
                        if (count++ % 3 == 0){
                            g.drawImage(imgs[step++ % 4 + 22],x,y,null);
                        }else {
                            g.drawImage(imgs[step % 4 + 22],x,y,null);
                        }
                        break;
                    default:
                        break;
                }
                break;

            case LEFT:
                switch (action){
                    case STAND:
                        // left stand
                        if (count++ % 3 == 0){
                            g.drawImage(imgs[step++ % 4 + 4],x,y,null);
                        }else {
                            g.drawImage(imgs[step % 4 + 4],x,y,null);
                        }
                        break;
                    case WALK:
                        // left walk
                        if (count++ % 3 == 0){
                            g.drawImage(imgs[step++ % 5 + 13],x,y,null);
                        }else {
                            g.drawImage(imgs[step % 5 + 13],x,y,null);
                        }
                        break;
                    case PRONE:
                        // left prone
                        g.drawImage(imgs[19],x - 15,y + 35,null);
                        break;
                    case JUMP:
                        // left jump
                        g.drawImage(imgs[21],x,y,null);
                        break;
                    case SHOOT:
                        // left shoot
                        if (count++ % 3 == 0){
                            g.drawImage(imgs[step++ % 4 + 26],x,y,null);
                        }else {
                            g.drawImage(imgs[step % 4 + 26],x,y,null);
                        }
                        break;
                    default:
                        break;
                }
                break;
            default:
                break;
        }
        blue.draw(g);
        bloodBar.draw(g);
        move();
    }

    @Override
    public void move() {
        if (left){
            x -= speed;
            this.action = Action.WALK;
        }
        if (right){
            x += speed;
            this.action = Action.WALK;
        }
        if (jump){
            jump(msc.grounds);
        } else {
            // 自由落体（往下掉）
            jumpDown(msc.grounds);
        }
        if (shoot){
            shoot();
        }
        if (pickup){
            pickup(msc.items);
        }
        if (this.x >= 1700 && this.x <= 1780 && this.y <= 360 - this.height){
            this.x = 100;
            this.y = 500;
        }

        confirmStatus();
        outOfBound();
    }

    /**
     * 射击持续时长的变量
     */
    private int shoot_count = 0;

    /**
     * 射击的方法
     */
    private void shoot() {
        shoot_count++;
        if (shoot_count % 10 == 0){

            shoot = false;
            this.MP -= 5;
            Arrow arrow;
            if (dir == Direction.RIGHT){
                arrow = new Arrow(msc,x + width,y + height / 2 + 8,dir);
            }else {
                arrow = new Arrow(msc,x,y + height / 2 + 8,dir);
            }
            msc.arrows.add(arrow);
        }
    }

    private double v0 = Constant.INIT_JUMP_SPEED;
    private double vt;
    private double g = 9.8;
    private double delta_height; // Δh
    private double t = 0.7;

    /**
     * 跳跃的方法
     */
    public void jump (List<Ground> grounds){
        if (!drop){
            // 向上跳（竖直上抛）
            vt = v0 - g * t;
            delta_height = v0 * t;
            v0 = vt;
            y -= delta_height;
            if (jump_again){
                v0 = Constant.INIT_JUMP_SPEED;
                jump_again = false;
            }
            // 上升到最高点 vt = 0 时，自由落体
            if (vt <= 0){
                vt = 0;
                drop = true;
            }
        } else {
            jumpDown(grounds);
        }
    }
    public boolean drop = true;
    public void jumpDown (List<Ground> grounds){
        // 向下掉的过程（自由落体）
        vt = v0 + g * t;
        delta_height = v0 * t;
        v0 = vt;
        y += delta_height;
        // 什么时候停止自由落体
        for (int i = 0; i < grounds.size(); i++) {
            Ground ground = grounds.get(i);
            if (this.getRectangle().intersects(ground.getRectangle()) &&
                this.y <= ground.y - this.height + 100){
                // 停止自由落体
                if (this.y >= ground.y - this.height){
                    this.y = ground.y - this.height;
                    drop = false;
                    jump = false;
                    v0 = Constant.INIT_JUMP_SPEED;
                    vt = 0.0;
                    break;
                }
            } else {
                drop = true;
            }
        }
    }
    /*private void jump() {
        // vt = v0 + gt
        // 竖直上抛与自由落体
        vt = v0 - g * t;
        delta_height = v0 * t;
        v0 = vt;
        y -= delta_height;

        // 自由落体的结束位置
        if (y >= 750){
            jump = false;
            v0 = Constant.INIT_JUMP_SPEED;
            vt = 0.0;
            y = 750;
        }
    }*/

    /**
     * 根据当前人物的开关，确定人物的方向
     */
    private void confirmStatus(){
        if (left && !right){
            this.dir = Direction.LEFT;
            // 朝左跳
            if (jump){
                this.action = Action.JUMP;
            }
        }else if (right && !left){
            this.dir = Direction.RIGHT;
            // 朝右跳
            if (jump){
                this.action = Action.JUMP;
            }
        }else if (down){
            this.action = Action.PRONE;
        }else if (jump){ // 原地跳
            this.action = Action.JUMP;
        }else if (shoot){
            this.action = Action.SHOOT;
        }
        // 左右都按下 或都不按 状态为STAND
        else {
            this.action = Action.STAND;
        }
    }

    /**
     * 按键的方法
     * @param e 按键事件对象
     */
    public void keyPressed(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_A:
                left = true;
                x -= speed;
                break;
            case KeyEvent.VK_D:
                right = true;
                x += speed;
                break;
            case KeyEvent.VK_S:
                down = true;
                break;
            case KeyEvent.VK_K: // 跳跃
                if (e.getKeyCode() == KeyEvent.VK_K && jump) {
                    jump_again = true;
                    y -= speed;
                }
                if (e.getKeyCode() == KeyEvent.VK_K) {
                    jump = true;
                    y -= speed;
                }
                break;
            case KeyEvent.VK_J: // 射击
                shoot = true;
                break;
            case KeyEvent.VK_L: // 拾取
                pickup = true;
                break;
            case KeyEvent.VK_I: // 打开道具包
                break;
            default:
                break;
        }
    }

    /**
     * 抬起键的方法
     * @param e 按键事件对象
     */
    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()){
            case KeyEvent.VK_A:
                left = false;
                break;
            case KeyEvent.VK_D:
                right = false;
                break;
            case KeyEvent.VK_S:
                down = false;
                break;
            case KeyEvent.VK_L: // 拾取
                pickup = false;
                break;
            default:
                break;
        }
    }






    /**
     * 人物出界问题
     */
    private void outOfBound() {
        if (this.x <= 0) {
            this.x = 0;
        }
        if (this.x >= Constant.GAME_WIDTH - this.width) {
            this.x = Constant.GAME_WIDTH - this.width;
        }

        if (this.dir == Direction.RIGHT){
            if (this.x >= 740 - this.width && this.y >= 725 - this.height && this.x <= 810 - this.width) {
                this.x = 740 - this.width;
            }
            if (this.x >= 810 - this.width && this.y >= 680 - this.height && this.x <= 945 - this.width) {
                this.x = 810 - this.width;
            }
            if (this.x >= 1410 - this.width && this.y >= 725 - this.height) {
                this.x = 1410 - this.width;
            }
            if (this.x >= 1480 - this.width && this.y >= 680 - this.height) {
                this.x = 1480 - this.width;
            }
            if (this.x >= 1550 - this.width && this.y >= 635 - this.height) {
                this.x = 1550 - this.width;
            }
        }
        if (this.dir == Direction.LEFT){
            /*if (this.x <= 1015 && this.y >= 725 - this.width && this.x >= 945 + this.width){
                this.x = 1015;
            }*/
            /*if (this.x <= 800 && this.y >= 650 - this.height + 40 && this.x >= 400) {
                this.x = 800;
            }*/
        }
    }

    /**
     * 拾取道具的方法
     * @param item 被拾取的道具对象
     * @return 是否拾取到
     */
    private boolean pickup(Item item){
        if (item.live && this.getRectangle().intersects(item.getRectangle())){
            item.live = false;
            // 存放之前和道具包中的每一个进行判断
            for (int i = 0; i < msc.itemPackage.items.size(); i++) {
                Item item1 = msc.itemPackage.items.get(i);
                // 如果相同 数量 +1
                if (item.type == item1.type) {
                    item1.qty += 1;
                    return false;
                }
            }
            // 业务 放入道具包
            msc.itemPackage.items.add(item); // 捡起来的道具
            /*msc.items.add(item);*/ // 打死小怪掉的道具

            /*switch (item.type){
                case 0:
                    this.HP += 50;
                    break;
                case 1:
                    this.HP += 100;
                    break;
                case 2:
                    this.HP += 300;
                    break;
                case 3:
                    this.MP += 100;
                    break;
                default:
                    break;
            }
            if (HP >= MAX_HP){
                HP = MAX_HP;
            }
            if (MP >= MAX_MP){
                MP = MAX_MP;
            }*/
        }
        return false;
    }

    /**
     * 拾取一堆道具
     * @param items 被拾取的道具对象容器
     * @return 是否拾取到
     */
    public boolean pickup(List<Item> items){
        for (int i = 0; i < items.size(); i++) {
            Item item = items.get(i);
            if (pickup(item)){
                return true;
            }
        }
        return false;
    }

    /**
     * 英雄与小怪进行碰撞检测的方法
     * @param mob 碰到的怪
     * @return 是否碰撞
     */
    /*private boolean hit(Mob mob){
        if (this.live && this.getRectangle().intersects(mob.getRectangle()) && mob.action != Action.DIE){
            this.HP -= 10;
            mob.action = Action.HIT;
            return true;
        }
        return false;
    }*/

    /**
     * 英雄与所有的怪进行碰撞检测的方法
     * @param mobs 怪物容器
     * @return 是否碰撞
     */
    /*public boolean hit(List<Mob> mobs){
        for (int i = 0; i < mobs.size(); i++) {
            Mob mob = mobs.get(i);
            if (hit(mob)){
                return true;
            }
        }
        return false;
    }*/

    /**
     * 画人物血条
     */
    public BloodBar bloodBar = new BloodBar();
    class BloodBar extends AbstractMapleStoryObject{
        private Image img;
        public BloodBar(){
            this.img = ImageUtil.getImage("hero_HP");
            this.width = img.getWidth(null);
        }
        @Override
        public void draw(Graphics g) {
            int n = Hero.this.width / this.width * Hero.this.HP / Hero.this.MAX_HP;
            for (int i = 0; i < n; i++) {
                g.drawImage(img,Hero.this.x + (i * this.width ),Hero.this.y - 20,null);
            }
        }
    }

    public Blue blue = new Blue();
    class Blue extends AbstractMapleStoryObject{
        private Image img;
        public Blue(){
            this.img = ImageUtil.getImage("hero_MP");
            this.width = img.getWidth(null);
        }
        @Override
        public void draw(Graphics g) {
            int n = Hero.this.width / this.width * Hero.this.MP / Hero.this.MAX_MP;
            for (int i = 0; i < n; i++) {
                g.drawImage(img,Hero.this.x + (i * this.width ),Hero.this.y - 10,null);
            }
        }
    }

}
